package net.kazed.nextaction.database;

import java.util.ArrayList;
import java.util.List;

import net.kazed.android.inject.Autowired;
import net.kazed.android.inject.Component;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

/**
 * DAO for Task records.
 */
@Component("taskDao")
public class TaskDao {

   private TaskContextTable taskContextTable = new TaskContextTable();
   private TaskJoinTable taskTable = new TaskJoinTable();
   private ContextTable contextTable = new ContextTable();
   private DatabaseHelper databaseHelper;

   @Autowired
   public void setDatabaseHelper(DatabaseHelper databaseHelper) {
      this.databaseHelper = databaseHelper;
   }

   public Cursor queryTasksByContext(int contextId, String whereClause) {
      final SQLiteDatabase db = databaseHelper.getReadableDatabase();
      StringBuffer where = new StringBuffer();
      where.append(TaskContextTable.TABLE).append(".").append(TaskContextTable.COLUMN_CONTEXT_ID).append("=?")
         .append(" and ").append(TaskContextTable.TABLE).append(".").append(TaskContextTable.COLUMN_TASK_ID)
         .append("=").append(Task.TABLE).append(".").append(Task.Column.ID);
      if (whereClause != null) {
         where.append(" and ").append(whereClause);
      }
      String[] whereArg = new String[] {Integer.toString(contextId)};
      Cursor cursor = taskTable.queryWithJoin(db, "task_context", taskTable.getColumnNames(),
            where.toString(), whereArg, Task.SORT_ORDER);
      return cursor;
   }
   
   /**
    * {@inheritdoc}
    */
   public List<TaskContext> getTaskContexts(int taskId) {
      List<TaskContext> taskContexts = new ArrayList<TaskContext>();
      final SQLiteDatabase db = databaseHelper.getReadableDatabase();
      Cursor cursor = null;
      try {
         final String whereClause = TaskContextTable.TABLE + "." + TaskContextTable.COLUMN_TASK_ID + "=?";
         final String[] whereArg = new String[] {Integer.toString(taskId)};
         cursor = taskContextTable.query(db, taskContextTable.getColumnNames(), whereClause, whereArg, null);
         cursor.moveToFirst();
         while (!cursor.isAfterLast()) {
            taskContexts.add(taskContextTable.extract(cursor));
            cursor.moveToNext();
         }
      } finally {
         cursor.close();
      }
      return taskContexts;
   }

   /**
    * {@inheritdoc}
    */
   public Uri save(TaskContext taskContext) {
      ContentValues values = taskContextTable.getValues(taskContext);
      SQLiteDatabase db = databaseHelper.getWritableDatabase();
      long id = taskContextTable.insert(db, values);
      updateContextNumberOfTasks(db, taskContext.getContextId());
      return TaskContext.ITEM_URI.buildUpon().appendPath(Long.toString(id)).build();
   }

//   /**
//    * {@inheritdoc}
//    */
//   public Uri update(TaskContext taskContext) {
//      ContentValues values = taskContextTable.getValues(taskContext);
//      SQLiteDatabase db = databaseHelper.getWritableDatabase();
//      Uri uri = TaskContext.ITEM_URI.buildUpon().appendPath(Long.toString(taskContext.getId())).build();
//      taskContextTable.update(db, uri, values);
//      return uri;
//   }

   /**
    * {@inheritdoc}
    */
   public Uri delete(TaskContext taskContext) {
      Uri uri = TaskContext.ITEM_URI.buildUpon().appendPath(Long.toString(taskContext.getId())).build();
      SQLiteDatabase db = databaseHelper.getWritableDatabase();
      taskContextTable.delete(db, uri);
      updateContextNumberOfTasks(db, taskContext.getContextId());
      return uri;
   }
   
   /**
    * Update the number of tasks count of a context.
    * @param db Database.
    * @param contextId ID of context.
    */
   private void updateContextNumberOfTasks(SQLiteDatabase db, int contextId) {
       Cursor cursor = null;
       try {
          final String whereClause = TaskContextTable.TABLE + "." + TaskContextTable.COLUMN_CONTEXT_ID + "=?";
          final String[] whereArg = new String[] {Integer.toString(contextId)};
          cursor = taskContextTable.query(db, taskContextTable.getColumnNames(), whereClause, whereArg, null);
          Uri uri = ContentUris.withAppendedId(GtdContext.CONTENT_ITEM_URI, contextId);
          int numberOfTasks = cursor.getCount();
          ContentValues values = new ContentValues();
          values.put(ContextTable.COLUMN_NUMBER_OF_TASKS, numberOfTasks);
          contextTable.update(db, uri, values);
       } finally {
          cursor.close();
       }
   }

   public void deleteTaskContextsByTask(int taskId) {
      SQLiteDatabase db = databaseHelper.getWritableDatabase();
      final String whereClause = TaskContextTable.TABLE + "." + TaskContextTable.COLUMN_TASK_ID + "=?";
      final String[] whereArg = new String[] {Integer.toString(taskId)};
      taskContextTable.delete(db, whereClause, whereArg);
   }

   public void deleteAllTaskContexts() {
      SQLiteDatabase db = databaseHelper.getWritableDatabase();
      taskContextTable.delete(db, null, null);
   }

}
